package de.alfenory.autobill;

import de.alfenory.autobill.logic.*;
import de.alfenory.autobill.config.*;
import de.alfenory.autobill.entity.*;


import java.util.*;
import java.util.logging.Logger;

/**
 * <p>This class creates an AutoBill Object. The main overview of activites are descripted in the following image.</p>
 * @author alexander.fenske@alfenory.de
 */
public class AutoBillFacade {

    private static final Logger log = Logger.getLogger(AutoBillFacade.class.getName());

    public static List<Autobill> getAutoBillList(
            AutobillConfiguration autobillConfig,
            Contact contact,
            List<Order> orderList,
            OrderitemsConfiguration oiConfig,
            DateConfiguration dateConfig, 
            TypeConfiguration typeConfig,
            List<Part> partList,
            List<TaxType> taxTypeList,
            int invoicenumber,
            int salesmanId, 
            int employeeId, 
            boolean onlyOrderItemsFromOrderItemsConfiguration) {

        List<Autobill> autoBillList = new ArrayList<Autobill>();
        
        List<Order> afterTermOrderList = new ArrayList<Order>();
        List<Order> beforeTermOrderList = new ArrayList<Order>();
        List<OrderItem> afterTermOrderItemList = new ArrayList<OrderItem>();
        List<OrderItem> beforeTermOrderItemList = new ArrayList<OrderItem>();
        
        
        
        if(!onlyOrderItemsFromOrderItemsConfiguration) {
            afterTermOrderList = OrderFacade.getOrder(orderList, autobillConfig, dateConfig, typeConfig, true);
            beforeTermOrderList = OrderFacade.getOrder(orderList, autobillConfig, dateConfig, typeConfig, false);
            afterTermOrderItemList = OrderFacade.getAllowedParts(afterTermOrderList, autobillConfig, typeConfig, dateConfig, true);
            beforeTermOrderItemList = OrderFacade.getAllowedParts(beforeTermOrderList, autobillConfig, typeConfig, dateConfig, false);
        }
        
        List<OrderItem> afterTermTaxIncludedOiList = new ArrayList<OrderItem>();
        List<OrderItem> afterTermTaxNotIncludedOiList = new ArrayList<OrderItem>();
        List<OrderItem> beforeTermTaxIncludedOiList = new ArrayList<OrderItem>();
        List<OrderItem> beforeTermTaxNotIncludedOiList = new ArrayList<OrderItem>();
        
        if(contact.isTaxIncluded()) {
            afterTermTaxIncludedOiList.addAll(afterTermOrderItemList);
            beforeTermTaxIncludedOiList.addAll(beforeTermOrderItemList);
        }
        else {
            afterTermTaxNotIncludedOiList.addAll(afterTermOrderItemList);
            beforeTermTaxNotIncludedOiList.addAll(beforeTermOrderItemList);
        }
        
        if(oiConfig!=null) {
            afterTermTaxIncludedOiList.addAll(oiConfig.addIndividuelAfterTermTaxIncludedOiList());
            afterTermTaxNotIncludedOiList.addAll(oiConfig.addIndividuelAfterTermTaxNotIncludedOiList());
            beforeTermTaxIncludedOiList.addAll(oiConfig.addIndividuelBeforeTermTaxIncludedOiList());
            beforeTermTaxNotIncludedOiList.addAll(oiConfig.addIndividuelBeforeTermTaxNotIncludedOiList());
            
            afterTermTaxIncludedOiList = oiConfig.filterOrderItems(afterTermTaxIncludedOiList, autobillConfig, !autobillConfig.isDailyMode() ? dateConfig.getDateAfterTerm() : dateConfig.getCurrentDate());
            afterTermTaxNotIncludedOiList = oiConfig.filterOrderItems(afterTermTaxNotIncludedOiList, autobillConfig, !autobillConfig.isDailyMode() ? dateConfig.getDateAfterTerm() : dateConfig.getCurrentDate());
            beforeTermTaxIncludedOiList = oiConfig.filterOrderItems(beforeTermTaxIncludedOiList, autobillConfig, dateConfig.getCurrentDate());
            beforeTermTaxNotIncludedOiList = oiConfig.filterOrderItems(beforeTermTaxNotIncludedOiList, autobillConfig, dateConfig.getCurrentDate());
        }
        
        if(afterTermTaxIncludedOiList.size() > 0) {
            invoicenumber++;
            autoBillList.add(getAutobill(autobillConfig, contact, afterTermTaxIncludedOiList, partList, taxTypeList, dateConfig, true, true, invoicenumber, salesmanId, employeeId));
        }
        if(afterTermTaxNotIncludedOiList.size() > 0) {
            invoicenumber++;
            autoBillList.add(getAutobill(autobillConfig, contact, afterTermTaxNotIncludedOiList, partList, taxTypeList, dateConfig, true, false, invoicenumber, salesmanId, employeeId));
        }
        if(beforeTermTaxIncludedOiList.size() > 0) {
            invoicenumber++;
            autoBillList.add(getAutobill(autobillConfig, contact, beforeTermTaxIncludedOiList, partList, taxTypeList, dateConfig, false, true, invoicenumber, salesmanId, employeeId));
        }
        if(beforeTermTaxNotIncludedOiList.size() > 0) {
            invoicenumber++;
            autoBillList.add(getAutobill(autobillConfig, contact, beforeTermTaxNotIncludedOiList, partList, taxTypeList, dateConfig, false, false, invoicenumber, salesmanId, employeeId));
        }

        return autoBillList;
    }

    /**
     * @param debtorMaster
     * @param oiList
     * @param stockMasterList
     * @param dateConfig
     * @param isAfterBillingTerm
     * @param isTaxIncluded
     * @param invoicenumber
     * @param salesmanId
     * @param employeeId
     * @return 
     */
    public static Autobill getAutobill(AutobillConfiguration autobillConfig, Contact contact, List<OrderItem> oiList, List<Part> partList, List<TaxType> taxTypeList, DateConfiguration dateConfig, boolean isAfterBillingTerm, boolean isTaxIncluded, int invoicenumber, int salesmanId, int employeeId) {
    
        Autobill autobill = new Autobill();
        Date date = isAfterBillingTerm  && !autobillConfig.isDailyMode() ? dateConfig.getDateAfterTerm() : dateConfig.getCurrentDate();
        autobill.setTransdate(date);
        autobill.setReference(autobillConfig.getBillReferencePretext()+invoicenumber);
        autobill.setPaymentTerm(contact.getPaymentTerm()); 
        autobill.getAutobillDetailList().addAll(AutobillDetailFacade.getAutobillDetailList(contact, oiList, partList, taxTypeList));
        autobill.getBookEntryList().addAll(BookEntryFacade.getBookEntryList(contact, oiList, date, autobillConfig, partList, taxTypeList, invoicenumber+""));
        autobill.setVatValue(BookEntryFacade.getVatValue(autobill.getBookEntryList(), taxTypeList));
        autobill.setValue(BookEntryFacade.getTotalValue(autobill.getBookEntryList(),contact));
        autobill.setTaxIncluded(contact.isTaxIncluded());
        
        
        
        return autobill;     
    }
}